<template>
  <el-dialog v-model="dialogVisible" :title="title" :width="width" :before-close="handleBeforeClose"
    :fullscreen="fullscreen" :draggable="draggable" :custom-class="customClass" @open="handleOpen" @close="handleClose">
    <el-form ref="formRef" :model="formData" :rules="formConfig.rules" :label-width="formConfig.labelWidth || '100px'"
      :label-position="formConfig.labelPosition || 'right'" :size="formConfig.size || 'default'"
      :disabled="formConfig.disabled || loading" :inline="formConfig.inline" class="crud-form">
      <el-row :gutter="formConfig.gutter || 20">
        <el-col v-for="field in formConfig.fields" :key="field.prop" :span="field.col?.span || 24"
          :offset="field.col?.offset" :push="field.col?.push" :pull="field.col?.pull">
          <el-form-item :label="field.label" :prop="field.prop" :class="field.class" :style="field.style">
            <!-- 输入框 -->
            <CrudInput v-if="field.type === 'input'" v-model="formData[field.prop]" :type="field.inputType || 'text'"
              :placeholder="field.placeholder" :disabled="field.disabled" :readonly="field.readonly"
              :maxlength="field.maxlength" :show-word-limit="field.showWordLimit"
              :show-password="field.showPassword === true" v-bind="field.attrs" />

            <!-- 文本域 -->
            <CrudInput v-else-if="field.type === 'textarea'" v-model="formData[field.prop]" type="textarea"
              :placeholder="field.placeholder" :disabled="field.disabled" :readonly="field.readonly"
              :maxlength="field.maxlength" :show-word-limit="field.showWordLimit" v-bind="field.attrs" />

            <!-- 选择器 -->
            <CrudSelect v-else-if="field.type === 'select'" v-model="formData[field.prop]"
              :placeholder="field.placeholder" :disabled="field.disabled" v-bind="field.attrs">
              <el-option v-for="option in field.options" :key="option.value" :label="option.label" :value="option.value"
                :disabled="option.disabled" />
            </CrudSelect>

            <!-- 单选框组 -->
            <el-radio-group v-else-if="field.type === 'radio'" v-model="formData[field.prop]" :disabled="field.disabled"
              v-bind="field.attrs">
              <el-radio v-for="option in field.options" :key="option.value" :label="option.value"
                :disabled="option.disabled">
                {{ option.label }}
              </el-radio>
            </el-radio-group>

            <!-- 复选框组 -->
            <el-checkbox-group v-else-if="field.type === 'checkbox'" v-model="formData[field.prop]"
              :disabled="field.disabled" v-bind="field.attrs">
              <el-checkbox v-for="option in field.options" :key="option.value" :label="option.value"
                :disabled="option.disabled">
                {{ option.label }}
              </el-checkbox>
            </el-checkbox-group>

            <!-- 日期选择器 -->
            <el-date-picker v-else-if="field.type === 'date'" v-model="formData[field.prop]" type="date"
              :placeholder="field.placeholder" :disabled="field.disabled" v-bind="field.attrs" />

            <!-- 日期时间选择器 -->
            <el-date-picker v-else-if="field.type === 'datetime'" v-model="formData[field.prop]" type="datetime"
              :placeholder="field.placeholder" :disabled="field.disabled" v-bind="field.attrs" />

            <!-- 数字输入框 -->
            <el-input-number v-else-if="field.type === 'number'" v-model="formData[field.prop]"
              :placeholder="field.placeholder" :disabled="field.disabled" v-bind="field.attrs" />

            <!-- 密码输入框 -->
            <CrudInput v-else-if="field.type === 'password'" v-model="formData[field.prop]" type="password"
              :placeholder="field.placeholder" :disabled="field.disabled" show-password v-bind="field.attrs" />

            <!-- 图片上传器 -->
            <div v-else-if="field.type === 'image-uploader'" class="image-uploader-container">
              <CrudImageUploader v-model="formData[field.prop]"
                :upload-mode="field.uploadConfig?.action ? 'immediate' : 'preview'" :validation-config="{
                  allowedTypes: field.uploadConfig?.allowedTypes || ['image/png', 'image/jpeg', 'image/gif', 'image/webp'],
                  maxSize: field.uploadConfig?.maxSize || 5
                }" :preview-config="field.uploadConfig?.preview || {
                  width: 120,
                  height: 120,
                  borderRadius: '8px'
                }" :upload-config="field.uploadConfig?.action ? {
                  action: field.uploadConfig.action,
                  name: field.uploadConfig.name || 'file',
                  data: field.uploadConfig.data || {}
                } : undefined" :disabled="field.disabled || loading"
                @upload-success="(result: Record<string, unknown>) => handleUploadSuccess(field.prop, result)"
                @upload-error="(error: string) => handleUploadError(field.prop, error)" />

              <!-- 上传提示信息 -->
              <div v-if="field.tip || field.description" class="upload-tips">
                <p v-if="field.tip" class="tip-title">{{ field.tip }}</p>
                <div v-if="field.description" class="tip-content" v-html="field.description"></div>
              </div>
            </div>

            <!-- 开关 -->
            <el-switch v-else-if="field.type === 'switch'" v-model="formData[field.prop]" :disabled="field.disabled"
              v-bind="field.attrs" />

            <!-- 滑块 -->
            <el-slider v-else-if="field.type === 'slider'" v-model="formData[field.prop]" :disabled="field.disabled"
              v-bind="field.attrs" />

            <!-- 评分 -->
            <el-rate v-else-if="field.type === 'rate'" v-model="formData[field.prop]" :disabled="field.disabled"
              v-bind="field.attrs" />

            <!-- 颜色选择器 -->
            <el-color-picker v-else-if="field.type === 'color-picker'" v-model="formData[field.prop]"
              :disabled="field.disabled" v-bind="field.attrs" />

            <!-- 时间选择器 -->
            <el-time-picker v-else-if="field.type === 'time'" v-model="formData[field.prop]"
              :placeholder="field.placeholder" :disabled="field.disabled" v-bind="field.attrs" />

            <!-- 时间选择器(固定时间) -->
            <el-time-select v-else-if="field.type === 'time-select'" v-model="formData[field.prop]"
              :placeholder="field.placeholder" :disabled="field.disabled" v-bind="field.attrs" />

            <!-- 字段提示信息 -->
            <div v-if="field.tip && field.type !== 'image-uploader'" class="field-tip">
              {{ field.tip }}
            </div>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>

    <template #footer>
      <div class="dialog-footer">
        <CrudButton v-if="showReset" type="primary" size="small" @click="handleReset">
          {{ resetText }}
        </CrudButton>
        <CrudButton type="primary" size="small" @click="handleCancel">
          {{ cancelText }}
        </CrudButton>
        <CrudButton type="danger" size="small" :loading="loading" @click="handleSubmit">
          {{ confirmText }}
        </CrudButton>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, reactive, computed, watch, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import type { FormInstance } from 'element-plus'
import type { CrudFormDialogProps, CrudFormDialogEvents } from './types'

/**
 * 组件属性定义
 */
const props = withDefaults(defineProps<CrudFormDialogProps>(), {
  title: '表单对话框',
  width: '600px',
  loading: false,
  confirmText: '确定',
  cancelText: '取消',
  beforeClose: false,
  showReset: false,
  resetText: '重置',
  fullscreen: false,
  draggable: false,
  customClass: '',
  autoClose: false,
})

/**
 * 事件定义
 */
const emit = defineEmits<CrudFormDialogEvents>()

/**
 * 表单引用
 */
const formRef = ref<FormInstance>()

/**
 * 对话框显示状态
 */
const dialogVisible = computed({
  get: () => props.visible,
  set: (value: boolean) => emit('update:visible', value)
})

/**
 * 表单数据
 */
const formData = reactive<Record<string, string | number | boolean | string[] | number[] | File | null>>({})

/**
 * 初始化表单数据
 */
const initFormData = () => {
  // 清空现有数据
  Object.keys(formData).forEach(key => {
    delete formData[key]
  })

  // 设置默认值
  props.formConfig.fields.forEach(field => {
    if (field.defaultValue !== undefined) {
      formData[field.prop] = field.defaultValue as string | number | boolean | string[] | number[] | File | null
    } else {
      // 根据字段类型设置默认值
      switch (field.type) {
        case 'checkbox':
          formData[field.prop] = []
          break
        case 'number':
        case 'slider':
        case 'rate':
          formData[field.prop] = 0
          break
        case 'switch':
          formData[field.prop] = false
          break
        default:
          formData[field.prop] = ''
      }
    }
  })

  // 合并传入的数据
  Object.assign(formData, props.modelValue)
}

/**
 * 监听表单数据变化
 */
watch(() => props.modelValue, (newValue) => {
  if (newValue) {
    // 清空现有数据
    Object.keys(formData).forEach(key => {
      delete formData[key]
    })
    // 重新初始化并合并新数据
    initFormData()
  }
}, { deep: true, immediate: true })

/**
 * 监听表单字段变化
 */
watch(formData, (newValue) => {
  emit('update:modelValue', { ...newValue })
}, { deep: true })

/**
 * 监听对话框显示状态
 */
watch(() => props.visible, (visible) => {
  if (visible) {
    nextTick(() => {
      initFormData()
    })
  }
})

/**
 * 处理表单提交
 */
const handleSubmit = async () => {
  try {
    if (!formRef.value) return

    // 表单验证
    await formRef.value.validate()

    // 触发提交事件
    emit('submit', { ...formData })

    // 自动关闭对话框
    if (props.autoClose) {
      dialogVisible.value = false
    }
  } catch (error) {
    console.error('表单验证失败:', error)
    emit('validate-error', error as Record<string, string[]>)
  }
}

/**
 * 处理取消操作
 */
const handleCancel = () => {
  emit('cancel')
  dialogVisible.value = false
}

/**
 * 处理重置操作
 */
const handleReset = () => {
  if (formRef.value) {
    formRef.value.resetFields()
  }
  initFormData()
  emit('reset')
}

/**
 * 处理对话框关闭前确认
 */
const handleBeforeClose = (done: () => void) => {
  if (props.beforeClose) {
    // 可以在这里添加确认逻辑
    done()
  } else {
    done()
  }
}

/**
 * 处理对话框打开
 */
const handleOpen = () => {
  emit('open')
}

/**
 * 处理对话框关闭
 */
const handleClose = () => {
  emit('close')
}

/**
 * 处理图片上传成功
 * @param prop - 字段名
 * @param result - 上传结果
 */
const handleUploadSuccess = (prop: string, result: Record<string, unknown>) => {
  console.log(`字段 ${prop} 上传成功:`, result)
  ElMessage.success('图片上传成功')
  emit('field-change', prop, formData[prop] || null)
}

/**
 * 处理图片上传错误
 * @param prop - 字段名
 * @param error - 错误信息
 */
const handleUploadError = (prop: string, error: string) => {
  console.error(`字段 ${prop} 上传失败:`, error)
  ElMessage.error(`图片上传失败: ${error}`)
}

/**
 * 暴露给父组件的方法
 */
defineExpose({
  /**
   * 验证表单
   */
  validate: () => formRef.value?.validate(),

  /**
   * 重置表单
   */
  resetFields: () => formRef.value?.resetFields(),

  /**
   * 清空验证
   */
  clearValidate: () => formRef.value?.clearValidate(),

  /**
   * 获取表单数据
   */
  getFormData: () => ({ ...formData })
})
</script>

<style lang="scss" scoped>
.crud-form {
  padding: 20px 0;

  :deep(.el-form-item__label) {
    font-weight: 500;
    color: #333;
  }
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

.image-uploader-container {
  display: flex;
  gap: 20px;
  align-items: flex-start;
}

.upload-tips {
  flex: 1;
  min-width: 280px;
  padding: 16px;
  background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
  border: 1px solid #dee2e6;
  border-radius: 8px;
  font-size: 13px;
  color: #495057;

  .tip-title {
    margin: 0 0 8px 0;
    font-weight: 600;
    color: #343a40;
    font-size: 14px;
  }

  .tip-content {
    line-height: 1.4;

    :deep(ul) {
      margin: 0 0 12px 0;
      padding-left: 16px;
      list-style-type: disc;

      li {
        margin-bottom: 4px;
      }
    }
  }
}

.field-tip {
  margin-top: 4px;
  font-size: 12px;
  color: #909399;
  line-height: 1.4;
}

// 深色模式
@media (prefers-color-scheme: dark) {
  .crud-form {
    :deep(.el-form-item__label) {
      color: $text-color-primary-dark;
    }
  }

  :deep(.el-dialog) {
    background-color: $bg-color-card-dark !important;
    border: 1px solid $border-color-light-dark;
  }

  :deep(.el-dialog__header),
  :deep(.el-dialog__body),
  :deep(.el-dialog__footer) {
    background-color: $bg-color-card-dark !important;
  }

  .dialog-footer {
    // 使用按钮组件自身暗色主题，不额外覆盖
    border-top: 1px solid transparent;
  }

  .upload-tips {
    background: linear-gradient(135deg, #1f2937 0%, #111827 100%);
    border-color: $border-color-light-dark;
    color: $text-color-secondary-dark;

    .tip-title {
      color: $text-color-primary-dark;
    }
  }

  .field-tip {
    color: $text-color-secondary-dark;
  }

  /* 追加：确保对话框本体与文字为暗色，并传递常用变量到子组件 */
  :deep(.el-dialog) {
    color: $text-color-primary-dark;
    --el-bg-color: #1f2937;
    --el-color-white: #1f2937;
    --el-fill-color-blank: #1f2937;
    --el-text-color-primary: #e5e7eb;
    --el-text-color-regular: #9ca3af;
    --el-border-color: #374151;
    --el-border-color-light: #374151;
    --el-border-color-lighter: #374151;
  }

  :deep(.el-dialog__title) {
    color: $text-color-primary-dark;
  }

  .crud-form {
    :deep(.el-form-item__content) {
      color: $text-color-primary-dark;
    }
  }

  :deep(.el-radio),
  :deep(.el-checkbox),
  :deep(.el-rate),
  :deep(.el-switch),
  :deep(.el-slider),
  :deep(.el-input-number) {
    color: $text-color-primary-dark;
  }
}

/**
 * 响应式设计
 */
@media (max-width: 768px) {
  .image-uploader-container {
    flex-direction: column;
    gap: 16px;
  }

  .upload-tips {
    min-width: auto;
  }
}
</style>

<style lang="scss">
@media (prefers-color-scheme: dark) {

  .el-overlay,
  .el-dialog,
  .el-dialog__body,
  .el-dialog__header,
  .el-dialog__footer {
    background-color: #1f2937 !important;
    color: #e5e7eb !important;
    border-color: #374151 !important;
  }

  .el-dialog__title {
    color: #e5e7eb !important;
  }

  .el-form-item__label {
    color: #d1d5db !important;
  }
}
</style>
